package com.lebang.controller.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lebang.aop.ConfigRecord;
import com.lebang.aop.Sessionid;
import com.lebang.common.Login;
import com.lebang.common.MemberLock;
import com.lebang.common.Require;
import com.lebang.component.RedisClient;
import com.lebang.component.UMengPushComponent;
import com.lebang.entity.LbbDict;
import com.lebang.entity.MemberRankRecord;
import com.lebang.entity.RankSort;
import com.lebang.entity.RequestHeaders;
import com.lebang.entity.member.LbbMember;
import com.lebang.model.MoneyCategory;
import com.lebang.model.QuerRankDate;
import com.lebang.model.RankModel;
import com.lebang.model.Whether;
import com.lebang.model.enums.RandRecordEnums;
import com.lebang.model.enums.RankEnums;
import com.lebang.model.enums.buss.TaskCategory;
import com.lebang.service.RankingService;
import com.lebang.service.buss.MemberService;
import com.lebang.service.buss.MemberTradeService;
import com.lebang.service.sys.DictService;
import com.lebangweb.common.TextUtil;
import com.lebangweb.response.Callback;
import com.lebangweb.response.JsonData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import redis.clients.jedis.Tuple;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @Author: hwq
 * @Date: 2019/11/4 10:36
 * @Version 1.0
 */
@Controller
@RequestMapping("/ranking")
public class RankingApi {
    public static final String RANKING_DAY = "RANKING_DAY";
    public static final String RANKING_WEEK = "RANKING_WEEK";
    @Autowired
    private RankingService rankingService;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private MemberService memberService;
    @Autowired
    private MemberTradeService memberTradeService;
    @Autowired
    private UMengPushComponent uMengPushComponent;
    @Autowired
    private DictService dictService;
    public static final String BANGDANG_ENABLE = "rankenable";

    @GetMapping("/sort")
    public String sort(Model model) {
        return "/sort/list";
    }

    @Login
    @PostMapping("/add/member")
    @ResponseBody
    public JsonData member(String phone, Integer money) {

        if ("18459270630".equals(phone) || "18650808266".equals(phone)) {
            LbbMember member = memberService.selectByPhone(phone);
            if (member == null) {
                return Callback.success("success", "修改失败");
            }
            rankingService.memberAddScore(member.getMemberId(), money);
            return Callback.success("success", "修改成功");
        } else {
            return Callback.success("error", "不支持修改");
        }
    }

    @PostMapping("/check/rank")
    @ResponseBody
    public JsonData check(RankSort sort) {
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("zhoubang",dictService.selectIntByKeyName("zhoubangkaiguan")>0);
        jsonObject.put("ribang",dictService.selectIntByKeyName("ribangkaiguan")>0);
        return Callback.success("success", "修改成功",jsonObject);
    }
    @PostMapping("/sort/edit")
    @ResponseBody
    @ConfigRecord
    public JsonData edit(RankSort sort) {
        rankingService.updateRankSort(sort);
        return Callback.success("success", "修改成功");
    }

    @GetMapping("/sort/add")
    public String sortadd(Model model) {

        model.addAttribute("sort", rankingService.getMaxSort() + 1);
        return "/sort/add";
    }

    @PostMapping("/sort/add")
    @ResponseBody
    public JsonData add(RankSort sort) {
        sort.setCreateTime(new Date());
        sort.setHasDeleted(Whether.NO.getDbIndex());
        rankingService.addRankSort(sort);
        return Callback.success("success", "修改成功");
    }

    @GetMapping("/data")
    public String dayRank() {
        int category = dictService.selectIntByKeyName("rank_page_category");
        if(category==0){
            return "/ranklist/rankPage";
        }else if(category==1){
            //大象兼职
            return "/ranklist/rankPageWL";
        }else if(category==2){
            //果果赚钱
            return "/ranklist/rankPageYM";
        }
        return "/ranklist/rankPage";
    }

    @GetMapping("/data1")
    public String sysRankPage() {

        return "/ranklist/page";
    }

    @PostMapping("/jsonData")
    @ResponseBody
    //@Login
    public JsonData jsonData(HttpServletRequest request, Integer page, Integer t) {
        return this.info(request, page, t,"123");
    }

    @PostMapping("/day")
    @ResponseBody
    @Require
    public JsonData info(HttpServletRequest request, Integer page, Integer t,String pass) {
        RequestHeaders requestHeaders = new RequestHeaders(request);
        RankModel myModel = new RankModel();
        String memberId = requestHeaders.getUserid();
        if (memberId == null) {
            memberId = "e40b3927811441308d52fa17c1be59ca";
        }

        Integer limit = 15;
        page = (page - 1) * limit;
        //上榜最低排行 redis是从0开始的所以减一
        int maxSort = rankingService.getMaxSort() - 1;
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //获取当前时间
        LocalDate now = LocalDate.now();
        LocalDateTime start;
        LocalDateTime end;
        String key;
        MemberRankRecord rankRecord;
        //日榜
        if (t == 0) {
            df = DateTimeFormatter.ofPattern("MM-dd HH:mm");
            rankRecord = rankingService.selectByMemberId(memberId, RankEnums.DAY.getIndex());
            key = RANKING_DAY;
            // 开始
            start = LocalDateTime.of(now, LocalTime.MIN);
            // 结束
            end = LocalDateTime.of(now, LocalTime.MAX);
        } else {
            df = DateTimeFormatter.ofPattern("MM-dd HH:mm");
            //周榜
            rankRecord = rankingService.selectByMemberId(memberId, RankEnums.WEEK.getIndex());
            key = RANKING_WEEK;
            TemporalAdjuster FIRST_OF_WEEK =
                    TemporalAdjusters.ofDateAdjuster(localDate -> localDate.minusDays(localDate.getDayOfWeek().getValue() - DayOfWeek.MONDAY.getValue()));
            start = LocalDateTime.of(now.with(FIRST_OF_WEEK), LocalTime.MIN);
            // 本周结束时间
            TemporalAdjuster LAST_OF_WEEK =
                    TemporalAdjusters.ofDateAdjuster(localDate -> localDate.plusDays(DayOfWeek.SUNDAY.getValue() - localDate.getDayOfWeek().getValue()));
            end = LocalDateTime.of(now.with(LAST_OF_WEEK), LocalTime.MAX);
        }

        String todayStartTime = start.format(df);
        String todayEndTime = end.format(df);
        //排行榜数据
        Set<Tuple> set = redisClient.zrevrangeWithScores(key, page, page + limit - 1);
        //排行榜计数
        Long size = redisClient.zcard(key);
        Set<Tuple> tuples = null;
        //我的排名
        Long my = redisClient.zrevrank(key, memberId);
        if (my == null) {
            my = 999L;
        }
        //今日收入
        Integer d = 0;
        //离上榜还差
        Double k = 0d;
        String text = "";
        String mytext = "";
        //有收入
        Double myScore = redisClient.zscore(key, memberId);
        if (myScore != null) {
            d = myScore.intValue();
        }
        //未上榜
        if (my == 0) {
            text = "恭喜独占鳌头,注意保持哦!";
            mytext = "";
        } else if (my > maxSort) {
            text = "再获{money}红包可进前奖励区抢红包";
            if (size < maxSort) {
                tuples = redisClient.zrevrangeWithScores(key, size - 1, size);
                mytext = "距离前" + size + "名{money}元";
            } else {
                tuples = redisClient.zrevrangeWithScores(key, maxSort - 1, maxSort);
                mytext = "距离前" + (maxSort + 1) + "名{money}元";
            }


        } else {
            text = "恭喜进入奖励区,再获{money}红包可晋升排名";
            tuples = redisClient.zrevrangeWithScores(key, (my - 2) < 0 ? 0 : (my - 2), my - 1);
            mytext = "再获{money}可晋升排名";

        }
        if (my > 0) {
            for (Iterator<Tuple> iterator = tuples.iterator(); iterator.hasNext(); ) {
                Tuple next = iterator.next();
                k = next.getScore();
            }
            Double m = k - d;
            text = text.replace("{money}", String.valueOf(new BigDecimal(m.intValue() + 1).divide(new BigDecimal(100))));
            mytext = mytext.replace("{money}", String.valueOf(new BigDecimal(m.intValue() + 1).divide(new BigDecimal(100))));
        }

        my = my + 1;
        myModel.setMsg(mytext);
        List<RankSort> sorts = rankingService.getList();
        List<RankModel> rankModels = new ArrayList<>();
        if (my > 100) {
            myModel.setSort("100+");
        } else {
            myModel.setSort(my);
        }
        LbbMember me = memberService.selectMemberById(memberId);
        myModel.setName(me.getNickname());
        myModel.setMemberId(memberId);
        int myMoney = rankingService.getDayMoneyForSort(my.intValue(), sorts, key);
        if (myMoney > 0) {
            myModel.setMoney(myMoney);
        } else {
            myModel.setMoney(0);
        }
        myModel.setScore(d);
        myModel.setImg(me.getAvatar());

        List<Tuple> data = new ArrayList<>(set);
        AtomicReference<Integer> sort = new AtomicReference<>(page + 1);
        for (Iterator<Tuple> iterator = data.iterator(); iterator.hasNext(); ) {
            Tuple s = iterator.next();
            RankModel model = new RankModel();
            model.setSort(sort.get());
            LbbMember member;
            String str = redisClient.get("member:" + s.getElement());
            if (str != null) {
                member = JSON.parseObject(str, LbbMember.class);
            } else {
                member = memberService.selectMemberById(s.getElement());
                if (member == null){
                    continue;
                }
                redisClient.setex("member:" + s.getElement(), JSON.toJSONString(member), 60);
            }
            if (TextUtil.isMobile(member.getNickname())) {
                model.setName("尾号" + member.getNickname().substring(member.getNickname().length() - 4));
            } else {
                model.setName(member.getNickname());
            }
            model.setMemberId(s.getElement());
            int myMoney1 = rankingService.getDayMoneyForSort(sort.get(), sorts, key);
            if (myMoney1 > 0) {
                model.setMoney(myMoney1);
            } else {
                model.setMoney(0);
            }
            Integer points = Double.valueOf(s.getScore()).intValue();
            model.setScore(points);
            sort.getAndSet(sort.get() + 1);
            rankModels.add(model);
        }

        rankRecord = this.checkRankRecord(rankRecord);
        Map map = new HashMap();
        map.put("maxSort", maxSort + 1);
        map.put("sbcount", k.intValue());
        map.put("record", rankRecord);
        if (rankRecord == null) {
            map.put("hasrecord", 0);
        } else {
            map.put("hasrecord", 1);
        }
        map.put("text", text);
        map.put("my", myModel);
        map.put("star", todayStartTime);
        map.put("end", todayEndTime);
        map.put("data", rankModels);
        return Callback.success("success", "查询成功", map);
    }


    private MemberRankRecord checkRankRecord(MemberRankRecord rankRecord) {
        if (rankRecord == null) {
            return null;
        }
        if (!rankRecord.getStatus().equals(0)) {
            return null;
        }
        if (!rankRecord.getCreateTime().plusDays(1).isAfter(LocalDateTime.now())) {
            rankRecord.setStatus(RandRecordEnums.FAIL.getIndex());
            rankRecord.setModifyTime(LocalDateTime.now());
            rankingService.updateRecord(rankRecord);
            return null;
        } else {
            return rankRecord;
        }
    }

    @ResponseBody
    @PostMapping("/get/record")
    @Require
    @MemberLock(ttl = 10000)
    public JsonData record(HttpServletRequest request) {
        RequestHeaders requsetHeader = new RequestHeaders(request);
        String memberId = requsetHeader.getUserid();
        MemberRankRecord rankRecord = rankingService.selectByMemberId(memberId);
        rankRecord = this.checkRankRecord(rankRecord);
        if (rankRecord != null) {
            rankRecord.setStatus(RandRecordEnums.SUCCESS.getIndex());
            rankRecord.setModifyTime(LocalDateTime.now());
            rankingService.updateRecord(rankRecord);
            memberTradeService.addMoney(memberId, rankRecord.getMoney(),
                    rankRecord.getTitle(), rankRecord.getMsg(), rankRecord.getId().toString(),
                    requsetHeader, JSON.toJSONString(rankRecord),new MoneyCategory(Whether.NO, TaskCategory.RANK_REBATE));
            try {
                uMengPushComponent.sendAndroidCustomizedcast(rankRecord.getTitle(), rankRecord.getMsg(), rankRecord.getMemberId());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return Callback.success("success", "领取成功");
        } else {
            return Callback.fail("success", "没有待领取的奖励");
        }
    }

    @ResponseBody
    @PostMapping("/getdate")
    @Require
    @Sessionid
    public JsonData JsonData(HttpServletRequest request, Integer type) {
        String str = redisClient.get("banddangrankdate");
        List<QuerRankDate> stringList = new ArrayList<>();
        if (str != null) {
            stringList = JSON.parseArray(str, QuerRankDate.class);

        } else {
            stringList = rankingService.getdate(type);

            if (type > 1) {
                stringList.forEach(s -> {
                    s.setShow(s.getQueryKey().substring(5, 7) + "." + s.getQueryKey().substring(8, 10) + "-" + s.getQueryKey().substring(16, 18) + "." + s.getQueryKey().substring(19, 21));
                    ;
                });
            } else {
                stringList.forEach(s -> {
                    s.setShow(s.getQueryKey().substring(5, 7) + "." + s.getQueryKey().substring(8, 10));
                });
            }
            if (stringList.size() > 0) {
                redisClient.setex("banddangrankdate" + type, JSON.toJSONString(stringList), 864000);
            }

        }

        return Callback.success("success", "查询成功", stringList);
    }


    @ResponseBody
    @PostMapping("/history")
    @Require
    @Sessionid
    public JsonData history(HttpServletRequest request, Integer type, String date) {
        RequestHeaders requestHeaders = new RequestHeaders(request);
        String memberId = requestHeaders.getUserid();
        List<MemberRankRecord> list = rankingService.history(type, date);
        list.forEach(s -> {

            if (TextUtil.isEmpty(s.getMemberName())) {
                LbbMember member;
                String str = redisClient.get("member:" + s.getMemberId());
                if (str != null) {
                    member = JSON.parseObject(str, LbbMember.class);
                } else {
                    member = memberService.selectMemberById(s.getMemberId());
                    redisClient.setex("member:" + s.getMemberId(), JSON.toJSONString(member), 600);
                }
                if (member != null) {

                    if (TextUtil.isMobile(member.getNickname())) {
                        s.setMemberName("尾号" + member.getNickname().substring(member.getNickname().length() - 4));
                    } else {
                        s.setMemberName(member.getNickname());
                    }

                }
            }
            if (memberId.equals(s.getMemberId())) {
                s.setStatus(99);
            }
        });

        return Callback.success("success", "查询成功", list);
    }

    public static void main(String[] args) {
        String str = "2019-11-25-2019-12-01";
        List<String> stringList = new ArrayList<>();
        stringList.add(str);
        stringList.forEach(s -> {

            s = s.substring(5, 7) + "." + s.substring(8, 10) + "-" + s.substring(16, 18) + "." + s.substring(19, 21);
          //  System.out.println(s);
        });

    }

    /**
     * 榜单显示控制
     **/
    @PostMapping("/rankenable")
    @ResponseBody
    public JsonData rankenable(Integer enable) {
        LbbDict dict = dictService.selectByKeyName(BANGDANG_ENABLE);
        return Callback.success("success", "查询成功", dict.getKeyvalue());
    }

    /**
     * 一键抢榜控制
     **/
    @PostMapping("/enable")
    @ResponseBody
    public JsonData enable(Integer enable) {
        LbbDict dict = dictService.selectByKeyName("yijianqiangban");
        return Callback.success("success", "查询成功", dict.getKeyvalue());
    }

    @GetMapping("/cooperation")
    public String cooperation() {
        return "/business/cooperation";
    }

    @GetMapping("/historyRank")
    public String historyRank(Model model, Integer type) {
        model.addAttribute("type", type);
        return "/ranklist/historyRank";
    }

    @ResponseBody
    @Require
    @Sessionid
    @PostMapping("/checkhasrecprd")
    public JsonData check(HttpServletRequest request) {
        RequestHeaders requestHeaders = new RequestHeaders(request);
        String memberId = requestHeaders.getUserid();
        Map map = new HashMap();
        MemberRankRecord rankRecord = rankingService.selectByMemberId(memberId, RankEnums.DAY.getIndex());
        MemberRankRecord rankRecord2 = rankingService.selectByMemberId(memberId, RankEnums.WEEK.getIndex());
        rankRecord = this.checkRankRecord(rankRecord);
        rankRecord2 = this.checkRankRecord(rankRecord2);
        if (rankRecord != null) {
            map.put("record", rankRecord);
            map.put("status", 1);
            return Callback.success("success", "查询成功", map);
        } else if (rankRecord2 != null) {
            map.put("record", rankRecord2);
            map.put("status", 1);
            return Callback.success("success", "查询成功", map);
        } else {
            map.put("status", 0);
            return Callback.fail("success", "查询成功", map);
        }

    }



    @ResponseBody
    @PostMapping("/getRewardMoney")
    public JsonData getRewardMoney(HttpServletRequest request) {

            return Callback.success("success", "查询成功",rankingService.getRewardMoney());
    }


}
